package com.starlink.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.core.convert.Convert;
import com.starlink.common.PageInfoTwo;
import com.starlink.common.utils.AssertUtil;
import com.starlink.model.dtomapper.ShoppingCartDetailDtoMapper;
import com.starlink.model.domain.ShoppingCartDetailDO;
import com.starlink.mapper.ShoppingCartDetailMapper;
import com.starlink.model.request.ShoppingCartDetailRequest;
import com.starlink.model.util.ShoppingCartDetailConvert;
import com.starlink.model.vo.MallBooksSpecificationVO;
import com.starlink.model.vo.MallPeripherySpecificationVO;
import com.starlink.model.vo.book.CartSpecificationVO;
import com.starlink.service.*;
import com.starlink.model.vo.ShoppingCartDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.starlink.utils.IDUtils.getId;

/**
 * @author zhanghong
 */
@Service
public class ShoppingCartDetailServiceImpl extends ServiceImpl<ShoppingCartDetailMapper, ShoppingCartDetailDO> implements ShoppingCartDetailService {
    @Autowired
    private ShoppingCartDetailMapper shoppingCartDetailMapper;
    @Autowired
    private MallBooksSpecificationService bookSpecificationService;
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private MallPeripheryService peripheryService;
    @Autowired
    private MallPeripherySpecificationService specificationService;

    private static final Integer BOOK = 1;
    private static final Integer RIM = 2;

    @Override
    public ShoppingCartDetailVO getByKey(long id) {
        ShoppingCartDetailVO shoppingCartDetailVO = ShoppingCartDetailDtoMapper.INSTANCE.do2VO(getById(id));
        return shoppingCartDetailVO;
    }

    @Override
    public PageInfoTwo<ShoppingCartDetailVO> pageQuery(ShoppingCartDetailRequest request) {
        long count = shoppingCartDetailMapper.pageCount(request);
        List<ShoppingCartDetailVO> list = shoppingCartDetailMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        return new PageInfoTwo(request.getPageNum(), request.getPageSize(), list, count);
    }

    @Override
    public List<ShoppingCartDetailVO> listQuery(ShoppingCartDetailRequest request) {
        List<ShoppingCartDetailDO> list = shoppingCartDetailMapper.selectDOList(ShoppingCartDetailDtoMapper.INSTANCE.request2DO(request));
        List<ShoppingCartDetailVO> shoppingCartDetailVOS = ShoppingCartDetailConvert.buildShoppingCartDetailVoList(list);
        return shoppingCartDetailVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(ShoppingCartDetailRequest request) {
        request.setId(getId());
        save(ShoppingCartDetailDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(ShoppingCartDetailRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(ShoppingCartDetailDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDOByIds(String ids) {
        shoppingCartDetailMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    @Override
    public Map<String, Long> getByUserId(long userId) {
        Map<String, Long> byUserId = shoppingCartDetailMapper.getCountByUserId(userId);
        return byUserId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addCarDetail(ShoppingCartDetailRequest request) {
        Integer mallType = request.getArticlesCategory();
        Long specificationId = request.getSpecificationId();
        Long carNum = request.getQuantity();
        Long cartId = shoppingCartService.addCar();
        //验证商品库存是否大于购物车商品数量
        if (BOOK == mallType) {
            MallBooksSpecificationVO specificationVO = bookSpecificationService.getByKey(specificationId);
            AssertUtil.assertNotNull(specificationVO, "商品规格不存在!");
            AssertUtil.assertTrue(carNum <= Optional.ofNullable(specificationVO.getInventory()).orElse(0L), "已超出库存!");
        } else if (RIM == mallType) {//周边商品
            MallPeripherySpecificationVO peripheryVO = specificationService.getByKey(specificationId);
            AssertUtil.assertNotNull(peripheryVO, "商品规格不存在!");
            AssertUtil.assertTrue(carNum <= Optional.ofNullable(peripheryVO.getInventory()).orElse(0L), "已超出库存!");
        } else {
            throw new RuntimeException("缺少商品类型!");
        }
        request.setIsOrNotBuy(0);
        ShoppingCartDetailDO shoppingCartDetailDO = ShoppingCartDetailDtoMapper.INSTANCE.request2DO(request);
        shoppingCartDetailDO.setShoppingCartId(cartId);
        Long quantity = shoppingCartDetailDO.getQuantity();
        ShoppingCartDetailDO cartDetailDO = shoppingCartDetailMapper.selectIsNotHave(shoppingCartDetailDO);
        if (cartDetailDO != null) {
            cartDetailDO.setQuantity(cartDetailDO.getQuantity() + quantity);
            cartDetailDO.setUpdateTime(new Date());
            shoppingCartDetailMapper.updateDO(cartDetailDO);
        } else {
            shoppingCartDetailDO.setId(getId());
            shoppingCartDetailMapper.insertDO(shoppingCartDetailDO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addCar(ShoppingCartDetailRequest request) {
        Integer mallType = request.getArticlesCategory();
        Long specificationId = request.getSpecificationId();
        Long carNum = request.getQuantity();
        if (BOOK == mallType) {
            MallBooksSpecificationVO specificationVO = bookSpecificationService.getByKey(specificationId);
            Long inventory = specificationVO.getInventory();
            if (carNum > inventory) {//验证商品库存是否大于购物车商品数量
                throw new RuntimeException("已超出库存!");
            }
        } else if (RIM == mallType) {//周边商品
            MallPeripherySpecificationVO peripheryVO = specificationService.getByKey(specificationId);
            Long inventory = peripheryVO.getInventory();
            if (carNum > inventory) {
                throw new RuntimeException("已超出库存!");
            }
        } else {
            throw new RuntimeException("缺少商品类型!");
        }
        ShoppingCartDetailDO cartDetailDO = new ShoppingCartDetailDO();
        cartDetailDO.setId(request.getId());
        cartDetailDO.setQuantity(request.getQuantity());
        shoppingCartDetailMapper.updateDO(cartDetailDO);
        return true;
    }

    @Override
    public List<ShoppingCartDetailVO> selectList(Long carId) {
        return shoppingCartDetailMapper.selectListDo(carId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleted(List<Long> orderCarProductIds) {
        shoppingCartDetailMapper.batchDeleted(orderCarProductIds);
    }

    @Override
    public List<CartSpecificationVO> selectCartSpecificationList(Long carId) {
        return shoppingCartDetailMapper.selectCartSpecificationList(carId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateByParam(Long carId, List<Long> articlesIdList) {
        shoppingCartDetailMapper.updateByParam(carId, articlesIdList);
    }
}
